package cn.itsource.basic.service.impl;

import cn.itsource.basic.domain.dto.SendSmsDto;
import cn.itsource.basic.exception.CustomException;
import cn.itsource.basic.service.IVerifyCodeService;
import cn.itsource.basic.util.StrUtils;
import cn.itsource.basic.util.VerifyCodeUtils;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public Object imageCode(String key) {
        //生成4位随机字符
        String code = StrUtils.getComplexRandomString(4);
        //存储redis，使用前端传来的key作为redis的key
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        //根据Code生成BASE64转码后的图片
        String base64 = VerifyCodeUtils.VerifyCode(110, 38, code);

        return base64;
    }

    @Override
    public void sendSmsCode(SendSmsDto dto) {
        //1. 空参数校验
        if (StringUtils.isEmpty(dto.getMobile())){
            throw new CustomException("手机号不能为空");
        }
        //2. 判断该手机号用户是否已经注册
        User user = userMapper.queryByUserName(dto.getMobile());
        //1. 如果注册过就返回自定义异常
        if (user != null){
            throw new CustomException("手机号已经注册");
        }
            //3. 根据前端传递过来的图片验证码的key，去redis中获取
        Object imageCode = redisTemplate.opsForValue().get(dto.getImageCodeKey());
            //1. 获取不到，返回自定义异常，图片验证码失效
        if(imageCode == null){
            throw new CustomException("图片验证码已失效！");
        }
            //4. 判断前端填写的图片验证码与redis中获取的是否一致
        if(!imageCode.toString().equalsIgnoreCase(dto.getImageCode())){
            //        1. 不一致，返回自定义异常，验证码不正确
            throw new CustomException("图片验证码错误！");
        }
            //5. 根据前端传递的手机号，拼接业务键去redis中查询
        String smsKey = dto.getMobile()+":register";
        Object smsCode = redisTemplate.opsForValue().get(smsKey);

        //定义一个公共的变量作为最终发送的验证码
        String resultCode = "";
            //1. 查询到有数据
        if(smsCode != null){
            //获取已经存在的短信验证码的时间戳
            String timeStamp = smsCode.toString().split(":")[1];
            //判断时间戳是否超过了1分钟重发时间
            if ((System.currentTimeMillis() - Long.parseLong(timeStamp)) <= 1*60*1000){
                throw new CustomException("请勿重复发送短信验证码！");
            }
            //没超过就更新redis的过期时间
            redisTemplate.opsForValue().set(smsKey,smsCode,3,TimeUnit.MINUTES);
            //准备发送老的验证码
            resultCode = smsCode.toString().split(":")[0];
        }else {
            //生成要发送的验证码
            String newSmsCode = StrUtils.getComplexRandomString(4);
            //生成要保存redis的value值
            String redisValueCode = newSmsCode+":"+System.currentTimeMillis();
            //保存到redis中，添加过期时间
            redisTemplate.opsForValue().set(smsKey,redisValueCode,3,TimeUnit.MINUTES);
            //准备发送新的验证码
            resultCode = newSmsCode;
        }
        //发送验证码
        //SmsUtils.sendSms(dto.getMobile(),"您好，您的验证码是:"+resultCode);
        System.out.println("您好，您的验证码是:"+resultCode);
    }
}




















